package com.lzp.java.concurrent.aqs;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @author lzp
 * @Description: 使用AQS实现一个线程协作器（一次性门闩）
 * @date 2021/3/7
 */
public class OneShotLatch {

    private final Sync sync = new Sync();

    private class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1627773084495514440L;

        @Override
        protected int tryAcquireShared(int arg) {
            // 判断状态值
            return getState() == 1 ? 1 : -1;
        }

        @Override
        protected boolean tryReleaseShared(int arg) {
            setState(1);
            return true;
        }
    }

    public void await() {
        sync.acquireShared(0);
    }

    public void signal() {
        sync.releaseShared(0);
    }

    public static void main(String[] args) throws InterruptedException {
        OneShotLatch latch = new OneShotLatch();
        ExecutorService pool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            pool.submit(() -> {
                System.out.println(Thread.currentThread().getName() + "已到达起点，等到latch信号。。。");
                latch.await();
                System.out.println(Thread.currentThread().getName() + "开始出发。。。");
            });
        }
        TimeUnit.SECONDS.sleep(3);
        latch.signal();

        // latch是一次性的
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "已到达起点，等到latch信号。。。");
            latch.await();
            System.out.println(Thread.currentThread().getName() + "开始出发。。。");
        }).start();
    }
}
